<?php
/**
 * [LICENCE]
 */

require_once ('Madoqua/Observer/Interface/Exception.php');

require_once 'Zend/Log.php';

require_once 'Zend/Log/Writer/Stream.php';

require_once 'Zend/Log/Writer/Firebug.php';

require_once 'Zend/Log/Formatter/Xml.php';


/**
 * Logging exception handler
 * @category   Madoqua
 * @package    Madoqua_Exception
 * @author     Graham Anderson - graham@andtech.eu
 * @copyright  Copyright (c) 2008
 */
class Madoqua_Exception_Log extends Zend_Log implements Madoqua_Observer_Interface_Exception
{
    /**
     * Logging config
     * @var Zend_Config
     */
    protected $_config;
    
    /**
     * Add the log writers with appropriate options
     * @todo enable/disable via config with null writer
     * @todo enable/disable via env? 
     */
    function __construct(Zend_Log_Writer $writer = null)
    {
        parent::__construct($writer);

        $this->_config = Madoqua_Application::getConfiguration()->environment->logging;
        
        if (!$this->_config->log_errors) {
            return;
        }        
        
        $this->addFireBugWriter();
        
        $context = null;
        if (Zend_Controller_Action_HelperBroker::hasHelper('ContextSwitcher')) {
            $contextSwitcher = Zend_Controller_Action_HelperBroker::getStaticHelper('ContextSwitcher');
            $context = $contextSwitcher->getCurrentContext();
        }
        
        // dont mangle ajax output, its a nightmare to debug with spammy exceptions
        if (!($context == 'ajax') && !($context == 'json')) {
            $this->addFileWriter();
        }   

        
    }
        
    /**
     * Handle the exception
     * @param Madoqua_Exception $e 
     * @see Madoqua_Exception_Observer_Interface::handle()
     */
    public function handle(Madoqua_Exception $e)
    {
        if (!$this->_config->log_errors) {
            return;
        }
        
        $message = $e->getMessage();
        $extras = array(
            'code'    => $e->getCode(),
            'file'   => $e->getFile(),
            'line'   => $e->getLine()            
        );
        
        foreach ($extras as $key => $value) {
            $this->setEventItem($key, $value);
        }
                
        switch ($e->getCode()) {
            case Madoqua_Exception::NOTICE:
            case Madoqua_Exception::USER:
                $this->info($message);
                break;
        	case Madoqua_Exception::WARNING:
        	    $this->warn($message);
        	    break;
        	case Madoqua_Exception::ERROR:
        	case Madoqua_Exception::CRITICAL:
        	    $this->emerg($message);
        	    break;
        	case Madoqua_Exception::DEBUG:
        	    $this->err($e);
        	    break;        	
        	default:
        	    $this->log($message, self::ALERT);
        		$this->_reThrow($e);
        	break;
        }
        
    }    
    
    /**
     * Add a file stream writer
     * @return Madoqua_Exception_Log
     */
    public function addFileWriter()
    {
        $logFile = Madoqua_Application::getDataDirectory() . 
                   DIRECTORY_SEPARATOR .
                   'log'.
                   DIRECTORY_SEPARATOR .
                   'errors.log';

        $fileWriter = new Zend_Log_Writer_Stream($logFile);
        
        switch ($this->_config->log_format) {
            case 0:
                $formatClass = new Zend_Log_Formatter_Xml('error', array(
                        'time'     => 'timestamp',
                        'level'    => 'priorityName',
                        'message'  => 'message',
                        'priority' => 'priority',
                        'file'     => 'file',
                        'line'     => 'line',
                    )
                );
                break;
            case 1:
                $formatClass = new Zend_Log_Formatter_Simple();
                break;
            default:
                $formatClass = new Zend_Log_Formatter_Xml();
        }
        $fileWriter->setFormatter($formatClass);
        
        $this->addWriter($fileWriter);

        return $this;
    }
    
    /**
     * Add fireBug log writer
     * @return Madoqua_Exception_Log
     */
    public function addFireBugWriter()
    {
        if($this->_config->fireBug->enabled &&
           $this->_config->fireBug->log_exceptions)
        {
           $fireBugWriter = new Zend_Log_Writer_Firebug();
           //$fireBugWriter->setDefaultPriorityStyle('TRACE');
           $this->addWriter($fireBugWriter);
        }
                
        return $this;
    }
    
    /**
     * If in doubt, throw it out
     * @param Madoqua_Exception $e 
     * @see Madoqua_Exception_Observer_Interface::reThrow()
     */
    public function reThrow(Madoqua_Exception $e)
    {
        throw $e;
    }
}